package com.gy.mbaselibrary.net;

import android.app.Activity;
import android.content.Context;

import com.google.gson.Gson;
import com.gy.mbaselibrary.App;
import com.gy.mbaselibrary.net.https.TrustAllCerts;
import com.gy.mbaselibrary.utils.FileUtil;
import com.gy.mbaselibrary.utils.LogUtil;
import com.gy.mbaselibrary.utils.StringUtil;
import com.gy.mbaselibrary.utils.UIUtils;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;

import java.io.File;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 创建者：高业
 * 邮箱：15234150168@163.com
 * 时间：2018/1/31
 * 类描述：接口的基类
 * 修改人：
 * 修改时间：2018/1/31
 * 修改备注：
 */
public class BaseRequest {
    //网络请求码
    protected int requestCode;
    ////网络请求回调接口
    protected ActivityResponseListener activityResponseListener;
    //参数
    protected Map<String, String> params;
    //上下文对象
    protected Context context;
    //tag
    protected Map<String,Object> tagMap = new HashMap<>();
    //解析类
    protected Class clz;
    //接口地址
    protected String url;
    //联网方式
    protected NetType type = NetType.POST;
    //header参数
    protected Map<String,String> headMap = new HashMap<>();

    protected String bodycontent;
    /*protected boolean isKey;*/
    //protected Object para;


    private final int READ_TIME_OUT = 30000;
    private final int CONNECT_TIME_OUT = 30000;
    private final int WRITE_TIME_OUT = 30000;

    /*public boolean isKey() {
        return isKey;
    }

    public void setKey(boolean key) {
        isKey = key;
    }

    public Object getPara() {
        return para;
    }

    public void setPara(Object para) {
        this.para = para;
    }*/

    public String getBodycontent() {
        return bodycontent;
    }

    public void setBodycontent(String bodycontent) {
        this.bodycontent = bodycontent;
    }

    public Map<String, Object> getTagMap() {
        return tagMap;
    }

    public void setTagMap(Map<String, Object> tagMap) {
        if (tagMap == null){
            return;
        }
        this.tagMap.putAll(tagMap);
    }

    public int getRequestCode() {
        return requestCode;
    }

    public ActivityResponseListener getActivityResponseListener() {
        return activityResponseListener;
    }

    public void setActivityResponseListener(ActivityResponseListener activityResponseListener) {
        this.activityResponseListener = activityResponseListener;
    }

    public Map<String, String> getParams() {
        return params;
    }

    public Context getContext() {
        return context;
    }


    public Class getClz() {
        return clz;
    }

    public void setClz(Class clz) {
        this.clz = clz;
    }

    public String getUrl() {
        return url;
    }

    public NetType getType() {
        return type;
    }

    public Map<String, String> getHeadMap() {
        return headMap;
    }

    public void setHeadMap(Map<String, String> headMap) {
        this.headMap = headMap;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    public void setRequestCode(int requestCode) {
        this.requestCode = requestCode;
    }


    public void setParams(Map<String, String> params) {
        this.params = params;
    }


    public void setClass(Class clz) {
        this.clz = clz;
    }

    public void setType(NetType type){
        this.type = type;
    }


    //设置回调
    public void setResponseListener(ActivityResponseListener activityResponseListener) {
        this.activityResponseListener = activityResponseListener;
    }

    //移除回调
    public void removeResponseListener() {
        this.activityResponseListener = null;
    }


    //解析
    private <T> T perResponse(String response, Class<T> clz) {
        Gson gson = new Gson();
        return gson.fromJson(response, clz);
    }

    //回调接口
    public interface ActivityResponseListener {
        public <T> void success(int requestCode, String url,T baseBean, String response, Object tag,Map<String,Object> tagMap,Map<String,String> params,Map<String,String> headParams);

        public void fail(int requestCode, String url,Exception e, Object tag,Map<String,Object> tagMap,Map<String,String> params,Map<String,String> headParams);

        public void parseNetworkResponse(int requestCode,String url,List<String> list);
    }

    //上传文件
    class FileUpdateCallBack implements Callback {

        @Override
        public void onFailure(Call call, final IOException exception) {
            if (activityResponseListener != null)
                activityResponseListener.fail(requestCode,url, exception, tagMap.get("tag"),tagMap,params,headMap);
        }

        @Override
        public void onResponse(Call call, final Response responseR) throws IOException {
            final String response = responseR.body().string();
            if (clz == null) {
                if (activityResponseListener != null) {
                    activityResponseListener.success(requestCode,url, null, response, tagMap.get("tag"),tagMap,params,headMap);
                }
            } else {
                if (activityResponseListener != null) {
                    activityResponseListener.success(requestCode, url,perResponse(response, clz), response, tagMap.get("tag"),tagMap,params,headMap);
                }
            }
        }
    }


    //调用接口
    public class OkHttpCallBack extends StringCallback {

        @Override
        public String parseNetworkResponse(Response response, int id) throws IOException {
            if (App.getInstance().isActivityRun(context.getClass().getName())){
                Headers headers = response.headers();
                Map<String, List<String>> map = headers.toMultimap();
                List<String> list = map.get("set-cookie");
                if (activityResponseListener != null)
                    activityResponseListener.parseNetworkResponse(requestCode,url,list);
            }

            return super.parseNetworkResponse(response, id);
        }

        @Override
        public void onError(Call call, final Exception e, int id) {
            LogUtil.i("url:" + url + " \nresponse:" + e.toString());
            UIUtils.post(new Runnable() {
                @Override
                public void run() {
                    if (App.getInstance().isActivityRun(context.getClass().getName())){
                        if (context instanceof Activity) {
                            Activity activity = (Activity) context;
                            if (!activity.isDestroyed()){
                                if (activityResponseListener != null)
                                    activityResponseListener.fail(requestCode,url, e, tagMap.get("tag"),tagMap,params,headMap);
                            }
                        }

                    }

                }
            });


        }



        @Override
        public void onResponse(final String response, int id) {
            LogUtil.i("url:" + url + " \nresponse:" + response);
            UIUtils.post(new Runnable() {
                @Override
                public void run() {
                    if (App.getInstance().isActivityRun(context.getClass().getName())){
                        if (context instanceof Activity) {
                            Activity activity = (Activity) context;
                            if (!activity.isDestroyed()){
                                if (App.getInstance().isDebug()){
                                    if (clz == null) {
                                        activityResponseListener.success(requestCode, url,null, response, tagMap.get("tag"),tagMap,params,headMap);
                                    } else {
                                        Object baseModel = perResponse(response, clz);
                                        activityResponseListener.success(requestCode, url,baseModel, response, tagMap.get("tag"),tagMap,params,headMap);
                                    }
                                }else {
                                    if (clz == null) {
                                        activityResponseListener.success(requestCode, url,null, response, tagMap.get("tag"),tagMap,params,headMap);
                                    } else {
                                        Object baseModel = perResponse(response, clz);
                                        activityResponseListener.success(requestCode, url,baseModel, response, tagMap.get("tag"),tagMap,params,headMap);
                                    }
                                }
                            }
                        }

                        //boolean hasOtherLogin = isHashOtherLogin(response);

                    }
                }
            });



        }
    }

    //执行
    public void execute() {
        if (params != null)
            params.put("vcode",App.getInstance().getVersionCode() + "");
        if (url.startsWith("https")) {
            if (NetType.GET == type) {
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                builder.sslSocketFactory(createSSLSocketFactory());
                builder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
                OkHttpClient client = builder.build();
                url = getResultUrl(url, params);
                OkHttpUtils.initClient(client).get().url(url)
                        .headers(headMap)
                        .build()
                        .readTimeOut(READ_TIME_OUT)
                        .writeTimeOut(WRITE_TIME_OUT)
                        .connTimeOut(CONNECT_TIME_OUT)
                        .execute(new OkHttpCallBack());
            } else if (NetType.POST == type){
                OkHttpClient.Builder ClientBuilder = new OkHttpClient.Builder();
                ClientBuilder.sslSocketFactory(createSSLSocketFactory());
                ClientBuilder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
                ClientBuilder.readTimeout(READ_TIME_OUT, TimeUnit.MILLISECONDS);//读取超时
                ClientBuilder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.MILLISECONDS);//连接超时
                ClientBuilder.writeTimeout(WRITE_TIME_OUT, TimeUnit.MILLISECONDS);//写入超时
                OkHttpClient client = ClientBuilder.build();
                //FormBody.Builder builder = new FormBody.Builder();

                MediaType JSON = MediaType.parse("application/json; charset=utf-8");

                    /*for (Map.Entry<String, String> entry : params.entrySet()) {
                        System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
                        builder.add(entry.getKey(),entry.getValue());
                    }*/
                RequestBody body = null;
                if (params == null || params.isEmpty()){
                    body = RequestBody.create(JSON, bodycontent);
                }else {
                    body = RequestBody.create(JSON, new Gson().toJson(params));
                }

                Headers.Builder headerBuilder = new Headers.Builder();
                if (headMap != null){
                    for (Map.Entry<String, String> entry : headMap.entrySet()) {
                        headerBuilder.add(entry.getKey(),entry.getValue());
                    }
                }

                Request request = new Request.Builder()
                        .headers(headerBuilder.build())
                        .url(url)
                        .post(body)
                        .build();
                client.newCall(request).enqueue(new CommonCallBack());
            }else if (NetType.PUT == type){
                OkHttpClient.Builder ClientBuilder = new OkHttpClient.Builder();
                ClientBuilder.sslSocketFactory(createSSLSocketFactory());
                ClientBuilder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
                ClientBuilder.readTimeout(READ_TIME_OUT, TimeUnit.MILLISECONDS);//读取超时
                ClientBuilder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.MILLISECONDS);//连接超时
                ClientBuilder.writeTimeout(WRITE_TIME_OUT, TimeUnit.MILLISECONDS);//写入超时
                OkHttpClient client = ClientBuilder.build();
                //FormBody.Builder builder = new FormBody.Builder();

                MediaType JSON = MediaType.parse("application/json; charset=utf-8");
                    /*for (Map.Entry<String, String> entry : params.entrySet()) {
                        System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
                        builder.add(entry.getKey(),entry.getValue());
                    }*/
                RequestBody body = null;
                if (params == null || params.isEmpty()){
                    body = RequestBody.create(JSON, bodycontent);
                }else {
                    body = RequestBody.create(JSON, new Gson().toJson(params));
                }

                Headers.Builder headerBuilder = new Headers.Builder();
                if (headMap != null){
                    for (Map.Entry<String, String> entry : headMap.entrySet()) {
                        headerBuilder.add(entry.getKey(),entry.getValue());
                    }
                }

                Request request = new Request.Builder()
                        .headers(headerBuilder.build())
                        .url(url)
                        .put(body)
                        .build();
                client.newCall(request).enqueue(new CommonCallBack());
            }

        }else {
            if (context instanceof Activity) {
                Activity activity = (Activity) context;
                if (NetType.GET == type) {
                    url = getResultUrl(url, params);
                    OkHttpUtils.get().url(url)
                            .headers(headMap)
                            .build()
                            .readTimeOut(READ_TIME_OUT)
                            .writeTimeOut(WRITE_TIME_OUT)
                            .connTimeOut(CONNECT_TIME_OUT)
                            .execute(new OkHttpCallBack());
                } else if (NetType.POST == type){
                    OkHttpUtils.post().url(url)
                            .headers(headMap)
                            .params(params)
                            .build()
                            .readTimeOut(READ_TIME_OUT)
                            .writeTimeOut(WRITE_TIME_OUT)
                            .connTimeOut(CONNECT_TIME_OUT)
                            .execute(new OkHttpCallBack());
                }else if (NetType.PUT == type){
                    OkHttpClient okHttpClient = new OkHttpClient();
                    FormBody.Builder builder = new FormBody.Builder();
                    if (params != null){
                        for (Map.Entry<String, String> entry : params.entrySet()) {
                            //System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
                            if (!StringUtil.isEmpty(entry.getKey()) && !StringUtil.isEmpty(entry.getValue())){
                                builder.add(entry.getKey(),entry.getValue());
                            }
                        }
                    }
                    FormBody body = builder.build();
                    //String format = getResultUrl(url,params);
                    Request.Builder requestBuilder = new Request.Builder();
                    if (headMap != null){
                        for (Map.Entry<String, String> entry : headMap.entrySet()) {
                            System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
                            requestBuilder.addHeader(entry.getKey(),entry.getValue());
                        }
                    }
                    //url = getResultUrl(url,params);
                    Request request = requestBuilder.url(url)
                            .put(body)
                            .build();
                    okHttpClient.newCall(request).enqueue(new CommonCallBack());
                }else if (NetType.DELETE == type){
                    OkHttpClient okHttpClient = new OkHttpClient();
                    FormBody.Builder builder = new FormBody.Builder();
                    if (params != null){
                        for (Map.Entry<String, String> entry : params.entrySet()) {
                            System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
                            builder.add(entry.getKey(),entry.getValue());
                        }
                    }
                    FormBody body = builder.build();
                    //String format = getResultUrl(url,params);
                    Request.Builder requestBuilder = new Request.Builder();
                    if (headMap != null){
                        for (Map.Entry<String, String> entry : headMap.entrySet()) {
                            System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
                            requestBuilder.addHeader(entry.getKey(),entry.getValue());
                        }
                    }
                    //url = getResultUrl(url,params);
                    Request request = requestBuilder.url(url)
                            .delete(body)
                            .build();
                    okHttpClient.newCall(request).enqueue(new CommonCallBack());
                }
            }
        }

    }


    class CommonCallBack implements Callback{

        @Override
        public void onFailure(Call call, final IOException e) {
            LogUtil.i("url:" + url + " \nresponse:" + e.toString());
            UIUtils.post(new Runnable() {
                @Override
                public void run() {
                    if (App.getInstance().isActivityRun(context.getClass().getName())){
                        if (context instanceof Activity) {
                            Activity activity = (Activity) context;
                            if (!activity.isDestroyed()){
                                if (activityResponseListener != null)
                                    activityResponseListener.fail(requestCode,url, e, tagMap.get("tag"),tagMap,params,headMap);
                            }
                        }
                    }

                }
            });
        }

        @Override
        public void onResponse(Call call, final Response response) throws IOException {
            //LogUtil.i("url:" + url + " \nresponse:" + response);
            final String resultstr = response.body().string();
            UIUtils.post(new Runnable() {
                @Override
                public void run() {
                    if (App.getInstance().isActivityRun(context.getClass().getName())){
                        if (context instanceof Activity) {
                            Activity activity = (Activity) context;
                            if (!activity.isDestroyed()){
                                if (App.getInstance().isDebug()){
                                    if (clz == null) {
                                        activityResponseListener.success(requestCode, url,null, resultstr, tagMap.get("tag"),tagMap,params,headMap);
                                    } else {
                                        Object baseModel = perResponse(resultstr, clz);
                                        activityResponseListener.success(requestCode, url,baseModel, resultstr, tagMap.get("tag"),tagMap,params,headMap);
                                    }
                                }else {
                                    if (clz == null) {
                                        activityResponseListener.success(requestCode, url,null, resultstr, tagMap.get("tag"),tagMap,params,headMap);
                                    } else {
                                        Object baseModel = perResponse(resultstr, clz);
                                        activityResponseListener.success(requestCode, url,baseModel, resultstr, tagMap.get("tag"),tagMap,params,headMap);
                                    }
                                }
                            }
                        }
                        //boolean hasOtherLogin = isHashOtherLogin(response);

                    }
                }
            });
        }
    }

    //GET方法路径拼接
    private String getResultUrl(String url, Map<String, String> params) {
        if (params == null){
            return url;
        }
        if (params.size() == 0){
            return url;
        }else {
            StringBuilder sb = new StringBuilder(url);
            sb.append("?");
            for (String key : params.keySet()) {
                sb.append(key);
                sb.append("=");
                sb.append(params.get(key));
                sb.append("&");
            }
            sb.deleteCharAt(sb.lastIndexOf("&"));
            return sb.toString();
        }

    }

    //判断是否有网络
    public Boolean isNetwork() {
        boolean flag = ConnectionHttp.connection_Internet(context);
        return flag;
    }

    //获取 SSLSocketFactory
    private static SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
        }

        return ssfFactory;
    }

    //上传图片
    public void updateImage(Map<String, List<String>> fileTypes) {
        if (context instanceof Activity){
            Activity activity = (Activity) context;
            final OkHttpClient client = new OkHttpClient();

            MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
            //遍历map中所有参数到builder
            if (params != null){
                for (String key : params.keySet()) {
                    builder.addFormDataPart(key, headMap.get(key));
                }
            }


            Headers.Builder headerBuilder = new Headers.Builder();
            if (headMap != null){
                for (Map.Entry<String, String> entry : headMap.entrySet()) {
                    headerBuilder.add(entry.getKey(),entry.getValue());
                }
            }
            /*
            builder.addFormDataPart("zfy", zfyJsonSecret);
            builder.addFormDataPart("ts", time + "");*/
            //遍历paths中所有图片绝对路径到builder，并约定key如“upload”作为后台接受多张图片的key
            //int i = 0;
            for (String key : fileTypes.keySet()) {
                List<String> urls = fileTypes.get(key);
                for (String path : urls) {
                    builder.addFormDataPart(key, FileUtil.getFileName(path),
                            RequestBody.create(MediaType.parse("file/" + FileUtil.getFileType(path)), new File(path)));

                }
            }
            //构建请求体
            RequestBody requestBody = builder.build();
            //构建请求
            Request request = new Request.Builder()
                    .headers(headerBuilder.build())
                    .url(url)//地址
                    .post(requestBody)//添加请求体
                    .build();
            client.newCall(request).enqueue(new FileUpdateCallBack());
        }


    }

    //获取类型
    private String getMediaType(String path) {
        return path.substring(path.lastIndexOf(".") + 1, path.length());
    }


    public static void main(String args[]) throws Exception {
        //System.err.println(generatePass());
        String data = "{\"phonenum\":\"15234150168\"}";

        //System.out.println(AESUtils.encryptAES(data));
        //System.out.println(decryptAES("2s7L+082dHKpSjc0KXy2+Q=="));
    }
}
